package jaspect.model;

import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Arjun
 */
public class AspectConfiguration {

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the serviceClassName
     */
    public String getServiceClassName() {
        return serviceClassName;
    }

    /**
     * @param serviceClassName the serviceClassName to set
     */
    public void setServiceClassName(String serviceClassName) {
        this.serviceClassName = serviceClassName;
    }

    /**
     * @return the mode
     */
    public InterceptMode getMode() {
        return mode;
    }

    /**
     * @param mode the mode to set
     */
    public void setMode(InterceptMode mode) {
        this.mode = mode;
    }

    /**
     * @return the params
     */
    public Properties getParams() {
        return params;
    }

    /**
     * @param props
     */
    public void setParams(Properties props) {
        this.params = props;
    }

    /**
     * @return the methods
     */
    public Map<String, AspectMethod> getMethods() {
        return methods;
    }

    /**
     * @param methods the methods to set
     */
    public void setMethods(Map<String, AspectMethod> methods) {
        //this.setMethods(methods);
        this.methods = methods;
    }

    /**
     */
   

    public static enum InterceptMode {

        /**
         * 
         */
        member,
        /**
         *
         */
        method
    }
    private String name;
    private String serviceClassName;
    private InterceptMode mode;
    private Properties params = new Properties();
    private Map<String, AspectMethod> methods = new HashMap<String, AspectMethod>();

    @Override
    public String toString() {
        return getName();

    }
    /**
     * This method is responsible for injecting the #db code for member aspect and is of no use in
     * method aspect
     * @param selMethods
     * @return # code for the given parameters
     */

    public String toAspectString(List<AspectMethod> selMethods) {
        StringBuilder temp = new StringBuilder();
        temp.append("#" + name + "\n");

        for (AspectMethod am : selMethods) {
            temp.append(am.toAspectString());
            temp.append("\n ");
        }

        temp.append("#\n");
        return temp.toString();

    }

    /**
     * This the final method that is responsible for generating the final code for member aspect
     * and it has nothing to do in the case of method aspect
     * @param methods
     * @return A string of  the method
     */
    public String toJavaString(Properties methods) {
        StringBuilder sb = new StringBuilder();


        if (this.mode == InterceptMode.member) {
            for (Enumeration mi = methods.keys(); mi.hasMoreElements();) {
                String methName = (String) mi.nextElement();
                String paramlist = methods.getProperty(methName);
                List params = Arrays.asList(paramlist.split(","));
                AspectMethod asm = getMethods().get(methName);
                Properties op = (Properties) asm.getArguments().clone();
                sb.append(methName + "() {\n\ttry{\n\t\t");
                sb.append(serviceClassName);
                sb.append(" service = new ");
                sb.append(serviceClassName);
                sb.append("();\n");
                sb.append("\t\tMap <String,String> params = new HashMap<String,String> ();\n");
                Iterator t = params.iterator();
                int i = 0;
                while (t.hasNext()) {
                    sb.append("\t\tparams.put(\"");
                    sb.append(params.get(i));
                    sb.append("\", this." + params.get(i) + ");\n");

                    i++;
                    t.next();
                }
                sb.append("\t\tservice" + "." + methName + "(getClass().getName(),params);\n\t}catch(Exception exception){\n\t\tthrow new RuntimeException(exception.getMessage());\n\t}\n");
                sb.append("}");
            }
        }


        return sb.toString();
    }


}

